﻿using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.Persistent.Base;
using DevExpress.Xpo;
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp.DC;
using DevExpress.Persistent.Validation;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.ConditionalAppearance;
using DevExpress.ExpressApp.Utils;
using DevExpress.ExpressApp.SystemModule;
using DomainComponents.Common;

namespace DomainComponents.XCRM {
    [DomainComponent]
    [NonPersistent]
    public class QualifyLeadParameters {
        public const string LeadQualifyContextId = "LeadQualify";
        public static Type QualifyLeadParametersType = typeof(QualifyLeadParameters);
        public static Type IContactObjectType = typeof(IContact);
        public static Type IAccountObjectType = typeof(IAccount);
        public static QualifyLeadParameters CreateQualifyLeadParameters() {
            return (QualifyLeadParameters)ReflectionHelper.CreateObject(QualifyLeadParametersType);
        }

        private static void CopyToCustomer(ILead lead, ICustomer customer) {
            customer.Owner = lead.Owner;
            customer.PreferredContactMethod = lead.PreferredContactMethod;
            if(lead is IPhones) {
                ((IPhones)lead).CopyTo(customer as IPhones);
            }
            lead.CopyTo(customer as ILeadTarget);
            if(lead is IAddressable) {
                ((IAddressable)lead).Copy(customer as IAddressable);
            }
        }
        protected virtual void QualifyCore(ILead lead, IObjectSpace os) {
            lead.Status = LeadStatus.Qualified;

            IContact contact = null;
            if(Contact) {
                contact = (IContact)os.CreateObject(IContactObjectType);
                CreatedCustomer = contact;

                contact.FirstName = lead.FirstName;
                contact.LastName = lead.LastName;
                CopyToCustomer(lead, contact);
            }
            if(Account) {
                IAccount account = (IAccount)os.CreateObject(IAccountObjectType);
                CreatedCustomer = account;

                account.AccountName = lead.CompanyName;
                account.SICCode = lead.SICCode;
                account.NumberOfEmployees = lead.NumberOfEmployees;
                account.WebSite = lead.WebSite;
                if(lead is IGenericEmail) {
                    ((IGenericEmail)lead).Copy(account as IGenericEmail);
                }

                if(Contact) {
                    account.Contacts.Add(contact);
                    account.PrimaryContact = contact;
                }
                CopyToCustomer(lead, account);
            }
        }
        protected virtual void QualifyCompleted(ILead lead, IObjectSpace os) {
            CreatedCustomer = (ICustomer)os.GetObject(CreatedCustomer);
        }

        public QualifyLeadParameters() {
        }

        public void Qualify(ILead lead, IObjectSpace os) {
            Guard.CheckObjectFromObjectSpace(os, lead);
            Validator.RuleSet.Validate(this, LeadQualifyContextId);

            using(IObjectSpace nos = os.CreateNestedObjectSpace()) {
                lead = nos.GetObject<ILead>(lead);
                QualifyCore(lead, nos);
                nos.CommitChanges();
                QualifyCompleted(lead, os);
            }
        }

        public bool Account { get; set; }
        public bool Contact { get; set; }

        [RuleFromBoolProperty("IsAccountOrContactSelected", LeadQualifyContextId, "You should select Contact or/and Account",
            UsedProperties = "Account,Contact")]
        [System.ComponentModel.Browsable(false)]
        public bool IsAccountOrContactSelected {
            get {
                return this.Account || this.Contact;
            }
        }

        [System.ComponentModel.Browsable(false)]
        public ICustomer CreatedCustomer { get; private set; }
    }

    [DomainComponent]
    [NonPersistent]
    public class QualifyLeadParametersWithOpportunity : QualifyLeadParameters {
        public static Type IOpportunityObjectType = typeof(IOpportunity);
        public bool Opportunity { get; set; }
        protected override void QualifyCore(ILead lead, IObjectSpace os) {
            base.QualifyCore(lead, os);
            if(Opportunity) {
                IOpportunity opportunity = (IOpportunity)os.CreateObject(IOpportunityObjectType);
                opportunity.PotentialCustomer = CreatedCustomer;
                opportunity.Name = lead.Topic;
                lead.CopyTo(opportunity as ILeadTarget);
            }
        }
    }
}
